
function createTemplate() {
    return data = [
        [{ "v": "$d{ ds.主键 }", bg: "#93c47d" }, { v: 234 }, null, null],
        [{ v: 567 }, { v: 234 }],
        // [{ v: 7 }, { v: 234 }],
        // [{ v: 5 }, { v: 234 }],
        // [{ v: 67 }, { v: 234 }],
        // [{ v: 23 }, { v: 234 }]
    ]
}
function createTestData() {
    return [[1, 33, "他"], [2, 44, "你"], [3, 55, "我"]],
}
function createDsm(column, data) {
    var ds = {
        name: "ds",
        columns: [{ name: "id", alias: "主键" }, { name: "age", alias: "年龄" }, { name: "name" }],
        data: data,
        get: function (param) {
            if (param.d === "") {//无方向
                if (param.a) {//错误设置
                    console.log("变量设置错误,无法找到对应行列数据:", param.o)
                    return []
                } else {//无功能名称，返回全部二维数据
                    return this.data
                }
            } else if (param.d != "") {//有方向
                if (param.a) {//有列名
                    if (param.a.toLowerCase() === "data") {//指定数据源的指定单元格
                        if (param.r && param.c) {//读取 data[r][c]单元格
                            return [this.data[param.r][param.c]]
                        } else {
                            console.log("变量设置错误，无法找到指定的单元格:", param.o)
                        }
                    } else {//是否取列的数据
                        const idx = this.getColIdx(param.a)
                        var cols = []
                        for (var i = 0; i < this.data.length; i++) {
                            cols.push(this.data[i][idx])
                        }
                        return cols
                    }
                } else {
                    console.log("变量设置错误，无法找到指定的单元格:", param.o)
                }
            }
        },
        getColIdx: function (name) {
            return this.columns.findIndex(column => {
                if (typeof column === "object") {
                    if (name.toLowerCase() === column.name.toLowerCase() || name.toLowerCase() === column.alias.toLowerCase()) {
                        return column
                    }
                } else {
                    if (name.toLowerCase() === column.toLowerCase()) {
                        return column
                    }
                }
            });
        }
    }
    return {
        datas: { ds: ds },
        get: function (name) {
            return this.datas[name]
        }
    }
}
function ds2cells(luckysheet) {
    luckysheet.create({
        container: 'luckysheet',
        data: [
            { data: data }
        ]
    })
    console.log("cells-0", data)

    var cells = JSON.parse(JSON.stringify(data))
    fillCell(cells, dsm)
    console.log("cells-1", cells)
    luckysheet.create({
        container: 'luckysheet',
        data: [
            { data: cells }
        ]
    })
}
/**
 * 根据模板id加载sheet
 * @param {*} sheetTplId sheet模板Id
 */
function loadSheet(sheetTplId) {

}
/**
 * 根据模板加载数据源
 * @param {*} dsConfig 数据源配置 
 */
function loadDataSource(dsConfig) {

}

/**
 * 向下填充单元格 
 * @param {*} cells 目标数据集 
 * @param {*} r 行
 * @param {*} c 列
 * @param {*} cell 单元格 
 * @param {*} value 填充值
 */
function fillCell(cells, dsm) {
    for (var r = 0; r < cells.length; r++) {
        for (var c = 0; c < cells[r].length; c++) {
            var cell = cells[r][c]
            if (cell && cell.v) {
                const reg = parseVariable(cell.v)
                if (reg) {
                    const ds = dsm.get(reg.ds)
                    var data = null
                    if (ds != null) { data = ds.get(reg) }
                    if (data) {
                        if (reg.d === "d") {
                            //数据源数据
                            //原cells需移动的数据
                            var range = []
                            for (var i = r + 1; i < cells.length; i++) {
                                range.push(cells[i][c])
                            }
                            //设置数据源数据
                            for (i = 0; i < data.length; i++) {
                                var v = { ...cell }
                                v.tv = cell.v
                                v.m = null
                                v.v = data[i]
                                setCell(cells, r + i, c, v)
                            }
                            //设置移动数据
                            for (var i = 0; i < range.length; i++) {
                                setCell(cells, r + data.length + i, c, range[i])
                            }
                        } else if (reg.d === "r") {
                            //原cells需移动的数据
                            var range = []
                            for (var i = c + 1; i < cells[0].length; i++) {
                                range.push(cells[r][i])
                            }
                            //设置数据源数据
                            for (i = 0; i < data.length; i++) {
                                var v = { ...cell }
                                v.tv = cell.v
                                v.m = null
                                v.v = data[i]
                                setCell(cells, r, c + i, v)
                            }
                            //设置移动数据
                            for (var i = 0; i < range.length; i++) {
                                setCell(cells, r, c + data.length + i, range[i])
                            }
                        } else if (reg.d === "") {
                            console.log("该变量模式暂不支持", reg)
                        }
                    }
                }
            }
        }
    }
}

function setCell(cells, r, c, cell) {
    //行
    var len = r + 1 - cells.length
    for (var i = 0; i < len; i++) {
        cells.push(new Array(cells[0].length).fill(null))
    }
    //列
    len = c + 1 - cells[0].length
    if (len > 0) {
        for (var j = 0; j < cells.length; j++) {
            cells[j].push(...new Array(len).fill(null))
        }
    }
    cells[r][c] = cell
}
/**
 * ${ds}  意味着在此单元格处，向右扩充列，向下扩充行
 * ${ds.data(1,2)} 在此处填充第1行，第2列的数据
 * $d{ds.row(1)} 在此处向下填充数据源第1行的数据
 * $d{ds.col(n)} 在此处向下填充数据源第n列或列名为n的列的数据
 * $d{ds.colName} 在此处向下填充
 * 
 */
function parseVariable(str) {
    if (typeof str != "string") { return undefined }
    const regex = /^\s*\r*\n*\t*\$([a-zA-Z]*)\s*\{\s*([a-zA-Z\u4e00-\u9fa5]+)\s*(\.\s*([a-zA-Z\u4e00-\u9fa5]+)\s*(\(\s*([^,]*)\s*(,\s*([^)]*)\s*)?\)\s*)?)?\}/;
    const match = str.match(regex);
    if (match) {
        return { o: match[0], d: match[1], ds: match[2], a: match[4], r: match[6], c: match[7] }
    }
    return undefined
}